home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / lang / c-part2 / 10010 < prev    next >
Encoding:
Text File  |  1996-08-05  |  5.5 KB  |  160 lines

  1. Path: news.bridge.net!news
  2. From: psycho@bridge.net (Gary Thompson)
  3. Newsgroups: comp.lang.c
  4. Subject: Re: NEwbie: How to return a multi-dimensional array from function?
  5. Date: Fri, 15 Mar 1996 07:44:42 GMT
  6. Organization: A poorly-installed InterNetNews site
  7. Message-ID: <4ib78s$6gv@news.bridge.net>
  8. References: <4hp273$8bu@news.xs4all.nl> <31404CE9.1A4A@mc.net> <mjs.826298629@hubcap>
  9. NNTP-Posting-Host: ppp-ftl1-28.bridge.net
  10. X-Newsreader: Forte Free Agent 1.0.81
  11.  
  12. mjs@hubcap.clemson.edu (M. J. Saltzman) wrote:
  13.  
  14. >Sean Park <spark@mc.net> writes:
  15.  
  16. >>Anthony Moendir wrote:
  17. >>> 
  18. >>> I want to return a multidimensional array from a function,
  19. >>> something like this:
  20. >>> 
  21. >>> char *Foo();
  22. >>> int main()
  23. >>> {
  24. >>>  char tmp[10][5];
  25. >>>  tmp=Foo();
  26. >>> }
  27. >>> 
  28. >>> char *Foo()
  29. >>> {
  30. >>>  char tmp[10][5];
  31.  
  32. >Two things: (1) If you are going to use the value of tmp outside of Foo(),
  33. >then you need to declare
  34. >    static tmp[10][5];
  35. >Otherwise the storage may disappear when you return from Foo().
  36.  
  37. No, declaring it as static will only retain the value in the foo() function, if
  38. you call it more than once.  You CANNOT use a value declared in a subfunction in
  39. MAIN.  You would have to remove both TMP declarations from MAIN and FOO and
  40. declare the thing globally outside of main.
  41.  
  42. >>> //do something
  43. >>> return(tmp);
  44. >           ^   ^ Parentheses not required here.
  45. >>> }
  46.  
  47. Makes no difference.  They are compiled the same either way.  Who would care
  48. about saving two bytes code space?
  49.  
  50. >(2) When you use tmp in an expression, the compiler replaces the array
  51. >name with a constant pointer to its first element.  (Among other
  52. >consequences, this means that arrays can't appear on the left side of
  53. >assignments.)  In this case, the first element has type
  54. >array-of-15-chars, so a pointer to it is a
  55. >pointer-to-array-of-15-chars.  That's the type that the function
  56. >should return, and the type of the variable that you assign it to.
  57. >Thus, Foo() needs to be declared
  58.  
  59. >    char (*Foo())[5];
  60. >and the tmp in main() should be 
  61. >    char (*tmp)[5];
  62.  
  63. WHAT???  You just declared five FUNCTION pointers pointed to nothing!  If you
  64. ran that, you'd get a NULL pointer error.  It wouldn't even run!  Again,
  65. declaring char (*tmp)[5] is declaring an array of five pointers to chars and
  66. assigning them to nothing... which will give you a NULL POINTER error AGAIN.
  67.  
  68. >>> How should i do that?
  69. >>> 
  70. >>> Any help would be appreciated
  71. >>> Anthony
  72.  
  73. >Another technique for getting the result back is to pass the array in as an
  74. >argument, as is done below (with corrections).
  75.  
  76. >>You could pass the pointer to the array to the function.  That way the 
  77. >>function itself will fill your array addresses rather than returning 
  78. >>redundant data.  You might try:
  79.  
  80. >>void foo(char *tmp);
  81. >          ^^^^^^^^^ Here, tmp should be declared char (*tmp)[5].
  82.  
  83. That wont work.  All pointers, require either 2 or 4 bytes (I forget which).
  84. You cannot pass data this way.  Chars only take up one byte.  If you pass an
  85. array of chars this way, you will get scrambled data at the other end.  It will
  86. try to interpret the passed chars as pointer addresses.  You will have to pass
  87. an array of POINTERS for this to work.  And you cannot pass arrays of anything.
  88.  
  89. >>int main()
  90. >>{
  91. >>   char tmp[10][5];
  92. >>   foo(tmp);
  93. >>   return 0;
  94. >>}
  95. >>void foo(char *tmp)
  96. >          ^^^^^^^^^ Here, tmp should be declared char (*tmp)[5].
  97.  
  98. Ok, since you declared foo() to accept only an array of five pointers at 2 bytes
  99. each, why are you passing it a single pointer?  When you pass it like foo(tmp),
  100. you are only passing it a single pointer to the beginning of the 2d array.  You
  101. will get one pointer and the rest garbage.
  102.  
  103. Besides, you are ignoring the question.  You are passing the data TO foo, he
  104. wants to return it from FOO.  Make it simple...  There are several ways of doing
  105. it easy...
  106. --------------------
  107. void foo(void);
  108. char tmp[10][5];
  109.  
  110. void main(void)
  111. {
  112.     foo();
  113.     /* do something else with tmp */
  114. }
  115.  
  116. void foo(void)
  117. {
  118.     /* do something with tmp */
  119. }
  120. -----------------
  121. That example allows you to access TMP within both main and foo.  Problem is,
  122. it's not very good with security...  tmp can be modified by ALL functions....
  123. not recommended if it's something critical.... This is a little more complicated
  124. but still easy...
  125. -----------------
  126. void foo(char *);
  127. main()
  128. {
  129.     char tmp[10][5];
  130.     foo(tmp);
  131. }
  132.  
  133. char *foo(char *tmp2)
  134. {
  135.     /* You can access tmp2 exactly like tmp... tmp2[10][5]...etc */
  136. }
  137. --------------------
  138. There are a few quirks with this also...  tmp2 is accessed exactly like tmp
  139. because it is the same thing.  tmp and tmp2 both access the same space.  That's
  140. why you don't have to return anything.  You can use tmp instead of tmp2, but it
  141. makes no difference.  tmp in main is a different variable than tmp in foo.  I
  142. like to use different variable names for the sake of clarity.
  143.  
  144. One problem with C is that the ONLY way you can pass the data in an array
  145. without passing just the pointer is by using a STRUCT.  passing the name of a
  146. struct is the only thing that will pass the data and not a pointer to the data.
  147. If you truly want to keep your variables independant, you will have to use a
  148. struct.
  149.  
  150. That is... unless you want to program in C++... you can then use the first
  151. example and declare which functions have permission to modify it.
  152.  
  153.                               Gary Thompson
  154.                                "The Psycho"
  155.                              psycho@bridge.net
  156.                         72607.1365@compuserve.com
  157.                        http://www.bridge.net/~psycho
  158.            HTTP://ourworld.compuserve.com/homepages/psychotps
  159.  
  160.